package work.jame.blog.framework.limit.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import work.jame.blog.framework.limit.AbstractRequestLimitHandler;
import work.jame.blog.framework.result.Result;
import work.jame.blog.framework.utils.http.IpUtils;
import work.jame.blog.framework.utils.http.WebUtils;
import work.jame.blog.framework.utils.redis.RedisService;
import work.jame.blog.framework.utils.redis.RedisUtils;
import work.jame.blog.pojo.BlackList;
import work.jame.blog.service.BlackListService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * 黑名单请求限制处理器
 *
 * @author : Jame
 * @date : 2023-05-13 14:22
 **/
@Component
public class BlackListRequestLimitHandler extends AbstractRequestLimitHandler {

    @Autowired
    private RedisService redisService;

    @Autowired
    private BlackListService blackListService;

    //禁用类型 临时
    private static final Integer DISABLE_TYPE_TEMPORARY = 1;
    //禁用类型 永久
    private static final Integer DISABLE_TYPE_PERMANENT = 2;

    @Override
    public Operation handler(HttpServletRequest request, HttpServletResponse response) {
        String ip = IpUtils.getIpAddr(request);
        String blackListIpKey = RedisUtils.getBlackListIpKey(ip);

        //首先根据ip查询是否存在黑名单中
        if (!redisService.hasKey(blackListIpKey)) {
            //如果缓存中没有则去查询数据库
            //无论是否存在都添加到缓存
            BlackList blackList = blackListService.queryBlackListByIp(ip);
            //如果为空说明没有在黑名单中
            if (Objects.isNull(blackList)) {
                redisService.setCacheObject(blackListIpKey, null);
            }
            redisService.setCacheObject(blackListIpKey, blackList);
        }

        BlackList blackList = redisService.getCacheObject(blackListIpKey);
        if (Objects.isNull(blackList)) {
            return Operation.ALLOW;
        }
        Integer disableType = blackList.getDisableType();
        if (DISABLE_TYPE_TEMPORARY.equals(disableType)) {
            //如果是临时禁用,则检查是否过了禁用时间
            if (LocalDateTime.now().isAfter(blackList.getUsableTime())) {
                //如果已经解除,删除掉缓存中的信息
                redisService.deleteObject(blackListIpKey);
                return Operation.ALLOW;
            }
        }
        //永久禁用则直接返回
        Result<?> result = Result.create(null, null, "你的ip已被禁用,请联系管理员");
        WebUtils.respondResult(response, result);
        return Operation.PROHIBIT;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
